/*
 * ===========================================================================
 *
 *       Filename:  IPRecordReader.h
 *
 *    Description:  Defination of IPRecordReader class and its derived classes
 *
 *         Author:  liangqing
 *
 * ===========================================================================
 */
#ifndef IPRECORDREADER_H
#define IPRECORDREADER_H

#include "IPRecord.h"
#include <deque>
#include <vector>

//#define USE_IFSTREAM

#ifdef USE_IFSTREAM
#include <fstream>
#endif /* USE_IFSTREAM */

/*
 *  Base class for reading ip record
 */
class IPRecordReader {
  public:
    virtual ~IPRecordReader(){ }

    virtual bool get(IPRecord *record) = 0;
    
  protected:
    static int split(const char *line, IPRecord *record);

    static inline const char *str2ip(const char *str, unsigned char *ip, size_t size);

    static inline bool is_space(const char c) {
        return (c == ' ' || c == '\t' || c == '\r' || c == '\n');
    }
};

/*  
 *  this class group readers into a queue, and provide records from the readers in the queue
 */
class IPRecordReaderQueue : public IPRecordReader {
  public:
    enum IPRecordReaderType{textfile=1, qqwry};

    typedef std::deque<IPRecordReader *> ReaderQueue;
    typedef std::string String;
    typedef std::vector<std::string> StringArray;
    
    IPRecordReaderQueue(const char *filters=NULL);

    ~IPRecordReaderQueue();

    virtual bool get(IPRecord *record);
    
    virtual void push_reader(IPRecordReaderType type, const char *filename);

  protected:
    inline bool _filter_string(IPRecord *record);
    
    bool _get(IPRecord *record);

    void _push_reader(IPRecordReaderType type, const char *filename);

    ReaderQueue _queue;

    StringArray _filters ;
};

/*
 *  this class read ip records from multiple-line text file
 */
class IPRecordTextfileReader : public IPRecordReader {
  public:
    //IPRecordTextFileReader constructor
    explicit IPRecordTextfileReader(const char *filename) {
#ifdef USE_IFSTREAM
        _textfile.open(filename);
#else
        _textfile = fopen(filename, "r");
        setvbuf(_textfile, NULL, _IOFBF , 4096);        
#endif /* USE_IFSTREAM */
    }

    virtual bool get(IPRecord *record);

  protected:
    inline bool getline(char *line, int size);
    
#ifdef USE_IFSTREAM
    //file stream for read
    std::ifstream _textfile;
#else
    FILE *_textfile;
#endif /* USE_IFSTREAM */
	char _line[4096];
};

/*
 *  this class read ip records from QQWry.Dat formatted file
 */
class IPRecordQQWryReader : public IPRecordReader {
  public:
    //IPRecordTextFileReader constructor
    //explicit IPRecordQQWryReader(const char *filename) : _qqwryfile(filename) { }
    
    virtual bool get(IPRecord *record);

  protected:
    //file stream for read
    //std::ifstream _qqwryfile;
};

#endif   /* #ifndef IPRECORDREADER_H */
